#!/usr/bin/env node

/**
 * 数据库恢复脚本
 * Database Restore Script
 */

const path = require('path');
const readline = require('readline');
const BackupService = require('../server/services/backup');
const logger = require('../server/utils/logger');

// 设置进程标题
process.title = 'personal-cloud-notes-restore';

/**
 * 创建命令行接口
 * Create command line interface
 */
function createInterface() {
  return readline.createInterface({
    input: process.stdin,
    output: process.stdout
  });
}

/**
 * 询问用户确认
 * Ask user for confirmation
 */
function askConfirmation(question) {
  const rl = createInterface();
  
  return new Promise((resolve) => {
    rl.question(`${question} (y/N): `, (answer) => {
      rl.close();
      resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
    });
  });
}

/**
 * 选择备份文件
 * Select backup file
 */
async function selectBackupFile(backupService) {
  const backups = await backupService.getBackupList();
  
  if (backups.length === 0) {
    console.log('❌ No backup files found.');
    process.exit(1);
  }

  console.log('\nAvailable backup files:');
  console.log('='.repeat(80));
  console.log('Index'.padEnd(8) + 'File Name'.padEnd(35) + 'Size'.padEnd(12) + 'Created At');
  console.log('-'.repeat(80));
  
  backups.forEach((backup, index) => {
    const indexStr = (index + 1).toString().padEnd(8);
    const fileName = backup.fileName.padEnd(35);
    const size = backupService.formatFileSize(backup.size).padEnd(12);
    const createdAt = backup.createdAt.toISOString();
    
    console.log(`${indexStr}${fileName}${size}${createdAt}`);
  });

  const rl = createInterface();
  
  return new Promise((resolve, reject) => {
    rl.question('\nSelect backup file (enter index number): ', (answer) => {
      rl.close();
      
      const index = parseInt(answer) - 1;
      if (isNaN(index) || index < 0 || index >= backups.length) {
        reject(new Error('Invalid selection'));
        return;
      }
      
      resolve(backups[index]);
    });
  });
}

/**
 * 显示恢复信息
 * Display restore information
 */
function displayRestoreInfo(backup) {
  console.log('\n' + '='.repeat(60));
  console.log('Database Restore Information');
  console.log('数据库恢复信息');
  console.log('='.repeat(60));
  console.log(`Backup file: ${backup.fileName}`);
  console.log(`File size: ${backup.size} bytes`);
  console.log(`Created at: ${backup.createdAt.toISOString()}`);
  console.log(`File path: ${backup.filePath}`);
  console.log('');
  console.log('⚠️  WARNING / 警告:');
  console.log('- This operation will replace all current data');
  console.log('- 此操作将替换所有当前数据');
  console.log('- A pre-restore backup will be created automatically');
  console.log('- 将自动创建恢复前备份');
  console.log('- This operation cannot be undone easily');
  console.log('- 此操作不易撤销');
  console.log('');
}

/**
 * 主恢复函数
 * Main restore function
 */
async function main() {
  const backupService = new BackupService();
  
  try {
    console.log('='.repeat(60));
    console.log('Personal Cloud Notes - Database Restore');
    console.log('个人云笔记 - 数据库恢复');
    console.log('='.repeat(60));
    console.log(`Start time: ${new Date().toISOString()}`);
    console.log('');

    // 选择备份文件
    const selectedBackup = await selectBackupFile(backupService);
    
    // 显示恢复信息
    displayRestoreInfo(selectedBackup);
    
    // 确认恢复操作
    const confirmed = await askConfirmation('Do you want to proceed with the restore?');
    if (!confirmed) {
      console.log('Restore operation cancelled.');
      process.exit(0);
    }

    // 询问是否创建恢复前备份
    const createPreBackup = await askConfirmation('Create pre-restore backup? (recommended)');
    
    console.log('\n🔄 Starting restore process...');
    console.log('正在开始恢复过程...');
    
    // 执行恢复
    const result = await backupService.performRestore(selectedBackup.fileName, {
      createPreRestoreBackup: createPreBackup
    });
    
    console.log('\n✅ Restore completed successfully!');
    console.log('恢复成功完成！');
    console.log('');
    console.log('Restore Details:');
    console.log(`  Restored from: ${selectedBackup.fileName}`);
    console.log(`  File size: ${backupService.formatFileSize(selectedBackup.size)}`);
    
    if (result.preRestoreBackup) {
      console.log(`  Pre-restore backup: ${result.preRestoreBackup.fileName}`);
    }
    
    if (result.verification.valid) {
      console.log('  Verification: ✅ Passed');
      console.log('  Table statistics:');
      Object.entries(result.verification.tableStats).forEach(([table, count]) => {
        console.log(`    ${table}: ${count} records`);
      });
    } else {
      console.log('  Verification: ❌ Failed');
      console.log(`  Error: ${result.verification.error}`);
    }
    
    console.log('');
    console.log(`End time: ${new Date().toISOString()}`);
    console.log('='.repeat(60));
    
    process.exit(0);
  } catch (error) {
    console.error('\n❌ Restore failed!');
    console.error('恢复失败！');
    console.error('Error:', error.message);
    console.error('');
    console.error('Stack trace:');
    console.error(error.stack);
    
    logger.error('Restore script failed:', error);
    process.exit(1);
  }
}

/**
 * 显示恢复历史
 * Show restore history
 */
async function showHistory() {
  const backupService = new BackupService();
  
  try {
    const history = await backupService.getRestoreHistory();
    
    console.log('Restore History:');
    console.log('='.repeat(80));
    
    if (history.length === 0) {
      console.log('No restore history found.');
      process.exit(0);
    }
    
    console.log('Time'.padEnd(25) + 'Backup File'.padEnd(35) + 'Status'.padEnd(10) + 'Pre-Backup');
    console.log('-'.repeat(80));
    
    for (const item of history) {
      const time = new Date(item.timestamp).toISOString().padEnd(25);
      const fileName = (item.backupFileName || 'N/A').padEnd(35);
      const status = (item.success ? '✅ Success' : '❌ Failed').padEnd(10);
      const preBackup = item.preRestoreBackup || 'None';
      
      console.log(`${time}${fileName}${status}${preBackup}`);
      
      if (!item.success && item.error) {
        console.log(`  Error: ${item.error}`);
      }
    }
    
    process.exit(0);
  } catch (error) {
    console.error('Failed to get restore history:', error.message);
    process.exit(1);
  }
}

/**
 * 验证备份文件
 * Verify backup file
 */
async function verifyBackup(fileName) {
  const backupService = new BackupService();
  
  try {
    const backups = await backupService.getBackupList();
    const backup = backups.find(b => b.fileName === fileName);
    
    if (!backup) {
      console.error(`Backup file not found: ${fileName}`);
      process.exit(1);
    }
    
    console.log(`Verifying backup: ${fileName}`);
    console.log('='.repeat(40));
    
    const result = await backupService.verifyBackupIntegrity(backup.filePath);
    
    if (result.valid) {
      console.log('✅ Backup file is valid');
      console.log(`Size: ${backupService.formatFileSize(result.size)}`);
      console.log(`Created: ${result.createdAt.toISOString()}`);
    } else {
      console.log('❌ Backup file is invalid');
      console.log(`Error: ${result.error}`);
      process.exit(1);
    }
    
    process.exit(0);
  } catch (error) {
    console.error('Failed to verify backup:', error.message);
    process.exit(1);
  }
}

/**
 * 处理命令行参数
 * Handle command line arguments
 */
function handleArguments() {
  const args = process.argv.slice(2);
  
  if (args.includes('--help') || args.includes('-h')) {
    console.log('Personal Cloud Notes - Database Restore Script');
    console.log('');
    console.log('Usage:');
    console.log('  node scripts/restore.js [options]');
    console.log('');
    console.log('Options:');
    console.log('  --help, -h        Show this help message');
    console.log('  --version, -v     Show version information');
    console.log('  --history         Show restore history');
    console.log('  --verify FILE     Verify backup file integrity');
    console.log('  --list            List available backup files');
    console.log('');
    console.log('Examples:');
    console.log('  node scripts/restore.js                    # Interactive restore');
    console.log('  node scripts/restore.js --history          # Show restore history');
    console.log('  node scripts/restore.js --verify backup.sql # Verify backup file');
    console.log('  node scripts/restore.js --list             # List backup files');
    process.exit(0);
  }
  
  if (args.includes('--version') || args.includes('-v')) {
    const packageJson = require('../package.json');
    console.log(`${packageJson.name} v${packageJson.version}`);
    process.exit(0);
  }
  
  return args;
}

/**
 * 列出备份文件
 * List backup files
 */
async function listBackups() {
  const backupService = new BackupService();
  
  try {
    const backups = await backupService.getBackupList();
    
    console.log('Available Backup Files:');
    console.log('='.repeat(80));
    
    if (backups.length === 0) {
      console.log('No backup files found.');
      process.exit(0);
    }
    
    console.log('File Name'.padEnd(35) + 'Size'.padEnd(12) + 'Created At');
    console.log('-'.repeat(80));
    
    for (const backup of backups) {
      const fileName = backup.fileName.padEnd(35);
      const size = backupService.formatFileSize(backup.size).padEnd(12);
      const createdAt = backup.createdAt.toISOString();
      
      console.log(`${fileName}${size}${createdAt}`);
    }
    
    process.exit(0);
  } catch (error) {
    console.error('Failed to list backups:', error.message);
    process.exit(1);
  }
}

// 处理未捕获的异常
process.on('uncaughtException', (error) => {
  console.error('Uncaught Exception:', error);
  logger.error('Uncaught exception in restore script:', error);
  process.exit(1);
});

process.on('unhandledRejection', (reason, promise) => {
  console.error('Unhandled Rejection at:', promise, 'reason:', reason);
  logger.error('Unhandled rejection in restore script:', reason);
  process.exit(1);
});

// 处理中断信号
process.on('SIGINT', () => {
  console.log('\n\nRestore operation cancelled by user.');
  process.exit(0);
});

// 主程序入口
if (require.main === module) {
  const args = handleArguments();
  
  if (args.includes('--history')) {
    showHistory();
  } else if (args.includes('--list')) {
    listBackups();
  } else if (args.includes('--verify')) {
    const fileIndex = args.findIndex(arg => arg === '--verify');
    const fileName = args[fileIndex + 1];
    if (!fileName) {
      console.error('Error: --verify requires a file name');
      process.exit(1);
    }
    verifyBackup(fileName);
  } else {
    main();
  }
}

module.exports = { main, showHistory, listBackups, verifyBackup };